package com.deyuanyun.pic.settings.service.msgtemplate;

import com.deyuanyun.pic.common.spring.SpringAppliction;
import com.deyuanyun.pic.settings.service.base.BizMsgThresholdIntefaceService;
import com.deyuanyun.pic.settings.service.base.BizMsgThresholdService;
import com.deyuanyun.pic.settings.task.PushMsgTask;
import com.google.common.base.Joiner;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.ContextLoader;

import javax.servlet.ServletContext;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  消息推送模板
 *  @author axiao(xj08.dream@gmail.com)
 *  @date 2016-08-08
 *  @version 1.0
 *  Histroy: [修改人][时间][描述]
 */
public abstract class AbstractPushMsgTemplate {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    protected BizMsgThresholdService bizMsgThresholdService;

    protected BizMsgThresholdIntefaceService bizMsgThresholdIntefaceService;

    protected MsgQueue msgQueue = MsgQueue.getInstance();

    public AbstractPushMsgTemplate() {
        bizMsgThresholdService = SpringAppliction.getBean(BizMsgThresholdService.class);
        bizMsgThresholdIntefaceService = SpringAppliction.getBean(BizMsgThresholdIntefaceService.class);
    }
    /** 需要推送的角色列表 */
    protected Collection<String> roleList;
    /** 阀值内容 */
    protected String thresholdContent;
    /** 接口参数 */
    protected Map interfaceParam = new HashMap();
    /** 是不是接口调用 */
    protected boolean isInterface = false;

    /**
     * 设置是否是接口调用，在isInterface设置为true的的时候必须给interfaceParam参数赋值
     * @param isInterface
     * @param dataMap
     */
    public void setInterface(boolean isInterface, Map dataMap) {
        this.isInterface = isInterface;
        if(dataMap != null)
            this.interfaceParam.putAll(dataMap);
    }

    /**
     * 将thresholdContentList转换为以逗号分割的字符串
     */
    public void thresListCastString(List thresList) {
        if(thresList != null && !thresList.isEmpty()) {
            this.thresholdContent = Joiner.on(",").skipNulls().join(thresList);
        }
    }

    /**
     * 发送消息提醒
     */
    public abstract void doPushMsgData();

    /**
     * 初始化需要发送的业务阀值消息
     * @param args
     */
    public abstract void initializeBizMsgSends(Object ... args);

    /**
     * 验证消息是否已经推送,返回true为已经推送
     * @param valiMap
     * @return
     */
    public abstract boolean valiIsPush(Map<String, Object> valiMap);

    /**
     * 推送消息
     */
    public final void pushMsg() {
        try {
            this.doPushMsgData();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        checkMsg();
    }

    /**
     * 检查是否有需要推送的消息,并判断任务是否启动，如任务不存在就创建
     */
    private void checkMsg() {
        if(msgQueue.size() > 0) {
            try {
                ServletContext servletContext =  ContextLoader.getCurrentWebApplicationContext().getServletContext();
                StdSchedulerFactory stdSchedulerFactory = (StdSchedulerFactory) servletContext.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);
                Scheduler scheduler = stdSchedulerFactory.getScheduler();
                String jobName = "msgQueue"; //任务名
                TriggerKey triggerKey = TriggerKey.triggerKey(jobName, Scheduler.DEFAULT_GROUP);
                if(!scheduler.checkExists(triggerKey)) { //消息推送任务不存在建立任务
                    SimpleTrigger trigger = TriggerBuilder.newTrigger().startNow().withIdentity(jobName, Scheduler.DEFAULT_GROUP)
                            .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(30).repeatForever()) //每30秒执行一次
                            .build();
                    JobDetail detail = JobBuilder.newJob(PushMsgTask.class)
                            .withIdentity(jobName, Scheduler.DEFAULT_GROUP).build();
                    scheduler.scheduleJob(detail, trigger);
                    scheduler.start();
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }
}
